package com.agen.basenet.util

import android.util.Log
import com.agen.basenet.annotation.ServiceUtil
import com.agen.basenet.converter.MyGsonConverterFactory
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import java.util.concurrent.TimeUnit

object NetManager {

    /**
     * 连接超时时间(秒)
     */
    private const val CONNECT_TIMEOUT = 10L

    /**
     * 读取数据超时时间(秒)
     */
    private const val READ_TIMEOUT = 10L

    private val okHttpClient by lazy {
        getClient()
    }

    private const val TAG = "NetManager"
    private var debug = false
    private var host: String = ""
    private val serviceMap = hashMapOf<String, Any>()

    private val interceptorList = mutableListOf<Interceptor>()

    fun setDebug(debug: Boolean) = this.apply {
        NetManager.debug = debug
    }

    fun setHost(host: String) = this.apply {
        NetManager.host = host
    }

    fun setHost(block: () -> String) = this.apply {
        host = block()
    }

    fun addInterceptor(interceptor: Interceptor) = this.apply {
        interceptorList.add(interceptor)
    }

    fun addInterceptors(interceptors: List<Interceptor>) {
        interceptorList.addAll(interceptors)
    }

    fun <S> getService(serviceClass: Class<S>): S {
        val className = serviceClass.name
        val service = serviceMap[className]
        return if (service == null) {
            val serviceParam = ServiceUtil.getServiceConfig(serviceClass)
            val hostUrl: String =
                serviceParam.baseUrl.ifBlank { host }
            val builder = Retrofit
                .Builder()
                .baseUrl(hostUrl)
                .client(okHttpClient)
                .addConverterFactory(MyGsonConverterFactory.create())
            val newService = builder.build().create(serviceClass)
            serviceMap[className] = newService!!
            newService
        } else {
            service as S
        }
    }

    private fun getClient(): OkHttpClient {
        var builder = OkHttpClient
            .Builder()
            .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
            .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)

        for (interceptor in interceptorList) {
            builder.addInterceptor(interceptor)
        }
        if (debug) {
            val loggingInterceptor = HttpLoggingInterceptor {
                Log.d(TAG, it)
            }
            loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
            builder = builder.addInterceptor(loggingInterceptor)
        }
        return builder.build()
    }
}